/* eslint-disable no-param-reassign */
import { createUUID } from 'qx-util';
import { isString } from 'lodash-es';
import { ref, watch, PropType, reactive, defineComponent } from 'vue';
import { clone, isElementSame, recursiveIterate } from '@ibiz-template/core';
import {
  IModal,
  IFilterNode,
  ISearchCondEx,
  calcSearchConds,
  ISearchCondGroup,
  IFilterNodeGroup,
  IFilterNodeCustom,
  SearchCondEx2filterNode,
} from '@ibiz-template/runtime';
import { useNamespace } from '@ibiz-template/vue3-util';
import { IFilterItem, ScriptValueRegex } from '../interfaces';
import { FilterTreeControl } from '../filter-tree/filter-tree';
import { OdooSearchBarController } from '../odoo-search-bar.controller';
import './modal.scss';

export const Modal = defineComponent({
  name: 'IBizModal',
  props: {
    item: { type: Object as PropType<IFilterItem> },
    modal: { type: Object as PropType<IModal>, required: true },
    controller: {
      type: Object as PropType<OdooSearchBarController>,
      required: true,
    },
  },
  setup(props) {
    const ns = useNamespace(`control-odoo-search-bar-modal`);

    const filterTreeRef = ref();

    const formRef = ref();

    const filterNodes = ref<IFilterNode[]>([]);

    const customCond = ref<string>('');

    const isInit = ref<boolean>(false);

    const data = reactive<IFilterItem>(
      clone(props.item) || {
        id: createUUID(),
        caption: '',
        showSeparator: false,
        searchconds: [{ condtype: 'GROUP', condop: 'AND', searchconds: [] }],
        isShow: true,
        isCustom: true,
        isChange: true,
      },
    );

    const original = props.controller.getSearchCondsById(data.id);

    const showRestore = ref<boolean>(
      !data.isCustom &&
        !!original &&
        (original.caption !== data.caption ||
          isElementSame(
            !data.searchconds || !data.searchconds.length
              ? [{ condtype: 'GROUP', condop: 'AND', searchconds: [] }]
              : original.searchconds,
            data.searchconds,
          )),
    );

    watch(
      () => data.caption,
      () => {
        if (!data.isCustom && original)
          showRestore.value = data.caption !== original.caption;
      },
    );

    watch(
      () => filterNodes.value,
      () => {
        if (!data.isCustom && original && isInit.value)
          showRestore.value = true;
      },
      {
        deep: true,
      },
    );

    /**
     * @description 初始化过滤节点数据
     */
    const initFilterNodes = (): void => {
      isInit.value = false;
      if (!data.searchconds || !data.searchconds.length)
        data.searchconds = [
          { condtype: 'GROUP', condop: 'AND', searchconds: [] },
        ];
      filterNodes.value = data.searchconds.map(item =>
        SearchCondEx2filterNode(item as ISearchCondEx),
      );
      if (filterNodes.value.length) {
        const { children } = filterNodes.value[0] as IFilterNodeGroup;
        if (Array.isArray(children)) {
          const index = children.findIndex(
            child => child.nodeType === 'CUSTOM' && child.customType === 'PQL',
          );
          if (index !== -1) {
            const item = children.splice(index, 1);
            customCond.value = (item[0] as IFilterNodeCustom)?.customCond || '';
          }
        }
        recursiveIterate(filterNodes.value[0], (node: IFilterNode) => {
          if (
            node.nodeType === 'FIELD' &&
            node.field &&
            node.valueOP &&
            isString(node.value) &&
            ScriptValueRegex.test(node.value)
          )
            node.disabled = true;
        });
      }
      setTimeout(() => {
        isInit.value = true;
      });
    };

    /**
     * @description 附加自定义条件
     * @param {IFilterNode[]} nodes
     * @returns {*}  {void}
     */
    const attachCustomCond = (nodes: IFilterNode[]): void => {
      if (!customCond.value) return;
      if (!nodes[0])
        nodes[0] = {
          nodeType: 'GROUP',
          logicType: 'AND',
          children: [],
        };
      const group = nodes[0] as IFilterNodeGroup;
      if (!Array.isArray(group.children)) {
        group.children = [];
      }
      const item = group.children.find(
        child => child.nodeType === 'CUSTOM' && child.customType === 'PQL',
      ) as IFilterNodeCustom;
      if (item) {
        item.customCond = customCond.value;
      } else {
        group.children.push({
          nodeType: 'CUSTOM',
          customType: 'PQL',
          customCond: customCond.value,
        });
      }
    };

    /**
     * @description 校验
     * @returns {*}  {Promise<boolean>}
     */
    const verify = async (): Promise<boolean> => {
      let state = filterTreeRef.value?.verify();
      try {
        await formRef.value?.validate();
      } catch (error) {
        state = false;
      }
      return state;
    };

    /**
     * @description 确认
     * @returns {*}  {Promise<void>}
     */
    const onConfirm = async (): Promise<void> => {
      // 先校验校验失败不做处理
      const result = await verify();
      if (!result) return;
      const nodes = clone(filterNodes.value);
      attachCustomCond(nodes);
      data.searchconds = calcSearchConds(nodes) as ISearchCondGroup[];
      if (!data.isCustom) data.isChange = showRestore.value;
      props.modal.dismiss({ ok: true, data: [data] });
    };

    /**
     * @description 取消
     */
    const onCancel = (): void => {
      props.modal.dismiss({ ok: false });
    };

    /**
     * @description 还原
     */
    const onRestore = async (): Promise<void> => {
      const result = await ibiz.confirm.warning({
        title: '警告',
        desc: `您确定要还原该筛选条件吗？还原后不可恢复！`,
      });
      if (result) {
        Object.assign(data, clone(original));
        initFilterNodes();
        showRestore.value = true;
      }
    };

    initFilterNodes();

    return {
      ns,
      data,
      isInit,
      formRef,
      customCond,
      showRestore,
      filterNodes,
      filterTreeRef,
      onCancel,
      onConfirm,
      onRestore,
    };
  },
  render() {
    return (
      <div class={this.ns.b()}>
        <div class={this.ns.e('header')}>
          <div>{!this.item ? '添加自定义筛选' : '变更筛选'}</div>
          {this.showRestore && (
            <el-button type='primary' onClick={this.onRestore}>
              还原
            </el-button>
          )}
        </div>
        <el-form
          ref='formRef'
          model={this.data}
          label-position='top'
          class={this.ns.e('content')}
          rules={{
            caption: [
              {
                required: true,
                message: '标题不能为空',
                trigger: 'blur',
              },
            ],
          }}
        >
          <el-form-item label='标题' prop='caption'>
            <el-input v-model={this.data.caption} placeholder='请输入标题' />
          </el-form-item>
          <FilterTreeControl
            ref='filterTreeRef'
            customCond={this.customCond}
            filterNodes={this.filterNodes}
            params={this.controller.params}
            context={this.controller.context}
            schemaEntityMap={this.controller.schemaEntityMap}
            filterControllers={this.controller.filterControllers}
            onCustomCondChange={val => {
              this.customCond = val;
            }}
          ></FilterTreeControl>
        </el-form>
        <div class={this.ns.e('footer')}>
          <el-button type='text' onClick={this.onCancel}>
            取消
          </el-button>
          <el-button type='primary' onClick={this.onConfirm}>
            确定
          </el-button>
        </div>
      </div>
    );
  },
});
